//
//  DNBaseViewModel.h
//  DNCodeConfuseDemo
//
//  Created by hushuaike on 17/8/21.
//  Copyright © 2017年 hushuaike. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DNBaseViewModelProtocal.h"

typedef void(^reactBlock)(id value, id viewModel);

#define DNGetPropertyName(property) NSStringFromSelector(@selector(property))

#define DNBindPropertyWithSeletor(vm, property, selector)\
{\
__weak typeof(self) welf = self;\
[vm bindProperty:DNGetPropertyName(property) withReactBlock:^(id value, id viewModel) {\
if ([welf respondsToSelector:selector]){\
[welf performSelector:selector withObject:value withObject:viewModel];\
}\
}];\
}

/**
 viewModel负责业务逻辑的处理，与UI分离，请确保viewModel在主线程中处理，需要异步处理的任务在viewModel内处理，处理后把结果返回到主线程中，
 在主线程中更新viewModel相关属性，UCSBaseViewModel为viewModel基类，子类需要继承该基类
 */

@interface DNBaseViewModel : NSObject

/**
 viewModel初始化方法
 
 @param delegate 传入初始代理对象，可以为空
 @return 新的viewModel实例
 */
- (instancetype)initWithDelegate:(id<DNViewModelProtocol>)delegate;

- (instancetype)init NS_UNAVAILABLE;

/**
 注册目标代理
 
 @param delegate 目标代理对象
 */
- (void)registerDelegate:(id<DNViewModelProtocol>)delegate;

/**
 解除目标代理的注册
 
 @param delegate 目标代理对象
 */
- (void)unregisterDelegate:(id<DNViewModelProtocol>)delegate;

/**
 把属性和目标对象绑定
 
 @param propertyName viewModel的属性
 @param target 目标对象
 */
- (void)bindProperty:(NSString *)propertyName withTarget:(id)target;


/**
 绑定属性
 
 @param propertyName 属性名
 @param block block
 */
- (void)bindProperty:(NSString *)propertyName withReactBlock:(reactBlock)block;


/**
 把属性和目标对象解绑
 
 @param propertyName viewModel的属性
 @param target 目标对象
 */
- (void)unbindProperty:(NSString *)propertyName withTarget:(id)target;


/**
 解绑属性
 
 @param propertyName 属性名
 @param block  block
 */
- (void)unbindProperty:(NSString *)propertyName withReactBlock:(reactBlock)block;

/**
 处理交互动作
 
 @param target 交互动作对象
 */
- (void)bindActionWithTarget:(id)target;

/**
 外部更新属性内容
 
 @param propertyName viewModel的属性
 @param value 更新值
 */
- (void)updateProperty:(NSString *)propertyName withValue:(id)value;
@end
